<?php declare(strict_types=1);

namespace App\Services\ElectronicSignature;

//电子签名流程-接口
use App\Models\Elec\ElecContracts;
use App\Models\Elec\ElecContractSignatories;
use App\Models\Elec\ElecOpenAccountRecords;
use App\Models\Store;
use App\Services\ElectronicSignature\Strategy\ElectronicSignatureInterface;
use App\Services\PrintSqlService;

class ElectronicSignature
{
    /**
     * @var ElectronicSignatureInterface
     */
    protected $electronicSignature;

    protected $api;

    public function __construct(ElectronicSignatureInterface $electronicSignature)
    {
        $this->electronicSignature = $electronicSignature;
        $this->api = $electronicSignature->getApi();
    }

    //申请开户

    /**
     * @return array
     */
    public function open(Store $store): array
    {
        try {
            $record = ElecOpenAccountRecords::query()->where([
                "api_type" => $this->api,
                "store_id" => $store->store_id,
            ])->first();
            if (!empty($record) && $record->open == 1) {
                throw new \Exception("已经开户");
            }
            $resultVo = $this->electronicSignature->open($store);
            //处理结果信息
            $userId = $resultVo->getData()["user_id"] ?? "";
            $body = $resultVo->getData()["body"] ?? [];
            if ($resultVo->getCode() == $resultVo->codeMap["ok"]) {
                $open = 1;
            } else {
                $open = 0;
            }
            //开户申请写入数据库
            if (empty($record)) {
                //写入开户数据
                $result = ElecOpenAccountRecords::query()->create([
                    "api_type" => $this->api,
                    "store_id" => $store->store_id,
                    "phone" => $store->people_phone,
                    "type" => $store->store_type == 2 ? 2 : 1,
                    "open" => $open,
                    "user_id" => $userId,
                    "signatoryName" => !empty($resultVo->getData()["signatoryName"]) ? $resultVo->getData()["signatoryName"] : "",
                    "context" => json_encode($body),
                ]);
            } else {
                //更新开户成功数据
                $record->user_id = $userId;
                $record->open = $open;
                $record->context = json_encode($body);
                $result = $record->save();
            }
            if (empty($result)) {
                throw new \Exception("更新数据失败");
            }
            return [
                "user_id" => $userId,
                "open" => $open,
                "error" => $resultVo->getMsg()
            ];
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage() . $e->getFile() . $e->getLine());
        }
    }

    //发送验证码
    public function sms(Store $store): array
    {
        $record = ElecOpenAccountRecords::query()->where([
            "api_type" => $this->api,
            "store_id" => $store->store_id,
        ])->first();
        if (empty($record)) {
            throw new \Exception("开户记录不存在");
        }
        $resultVo = $this->electronicSignature->sms([
            "userId" => (string)$record->user_id,
            "storeArray" => $store->toArray()
        ]);
        if ($resultVo->getCode() == $resultVo->codeMap["failed"]) {
            throw new \Exception($resultVo->getMsg());
        }
        return [
            "randomCode" => $resultVo->getData()["randomCode"] ?? ""
        ];
    }

    //创建合同
    public function createContract(array $param): array
    {
        if (empty($param["code"])) {
            throw new \Exception("短信验证码不存在");
        }
        if (empty($param["store_id"])) {
            throw new \Exception("店铺ID不能为空");
        }
        if (empty($param["company"])) {
            throw new \Exception("通道不能为空");
        }
        if (empty($param["remark"])) {
            throw new \Exception("备注不能为空");
        }

        $store = Store::query()->where("store_id", $param["store_id"])->first();
        if (empty($store)) {
            throw new \Exception("店铺不存在");
        }
        //创建合同需要先检查是否开户
        $record = ElecOpenAccountRecords::query()->where([
            "api_type" => $this->api,
            "store_id" => $store->store_id,
        ])->first();
        if (empty($record) || $record->open == 0) {
            throw new \Exception("请先开户");
        }
        $resultVo = $this->electronicSignature->createContract($param["code"],
            [
                "user_id" => $record->user_id,
                "store_id" => $store->store_id,
                "company" => $param["company"],
                "randomCode" => $param["randomCode"] ?? ""
            ]
        );
        $contractState = 0;
        if ($resultVo->getCode() == $resultVo->codeMap["ok"]) {
            //合同创建成功
            $elec = ElecContracts::query()->where(["store_id" => $store->store_id, "company" => $param["company"]])->first();
            if (empty($elec)) {
                $elec = ElecContracts::query()->create([
                    "store_id" => $store->store_id,
                    "api_type" => $this->api,
                    "company" => $param["company"],
                    "type" => $record->type,
                    "remark" => $param["remark"],
                    "contractNo" => $resultVo->getData()["contractNo"] ?? "",
                    "contractType" => $resultVo->getData()["contractTypeCode"] ?? "",
                    "contractTypeName" => $resultVo->getData()["contractTypeName"] ?? "",
                    "contractName" => $resultVo->getData()["contractName"] ?? "",
                    "contractState" => $resultVo->getData()["contractState"] ?? 0,
                    "contractCreateTime" => $resultVo->getData()["createTime"] ?? date("Y-m-d H:i:s", time()),
                    "expiredDate" => $resultVo->getData()["expiredDate"] ?? null,
                    "signatoryName" => $record->signatoryName,
                    "contractUrl" => "",
                    "projectCode" => $resultVo->getData()["projectCode"] ?? "",
                    "checkCode" => $resultVo->getData()["checkCode"] ?? "",
                ]);
                $contractState = $resultVo->getData()["contractState"] ?? 0;
                //签署人信息记录
                ElecContractSignatories::query()->create([
                    "elec_contract_id" => $elec->id,
                    "type" => $record->type,
                    "context" => json_encode(empty($resultVo->getData()["signatories"]) ? [] : $resultVo->getData()["signatories"]),
                ]);
            } else {
                ElecContracts::query()->where(["store_id" => $store->store_id, "company" => $param["company"]])->update([
                    "store_id" => $store->store_id,
                    "api_type" => $this->api,
                    "company" => $param["company"],
                    "type" => $record->type,
                    "remark" => $param["remark"],
                    "contractNo" => $resultVo->getData()["contractNo"] ?? "",
                    "contractType" => $resultVo->getData()["contractTypeCode"] ?? "",
                    "contractTypeName" => $resultVo->getData()["contractTypeName"] ?? "",
                    "contractName" => $resultVo->getData()["contractName"] ?? "",
                    "contractState" => $resultVo->getData()["contractState"] ?? 0,
                    "contractCreateTime" => $resultVo->getData()["createTime"] ?? date("Y-m-d H:i:s", time()),
                    "expiredDate" => $resultVo->getData()["expiredDate"] ?? null,
                    "signatoryName" => $record->signatoryName,
                    "contractUrl" => "",
                    "projectCode" => $resultVo->getData()["projectCode"] ?? "",
                    "checkCode" => $resultVo->getData()["checkCode"] ?? "",
                ]);
                ElecContractSignatories::query()->where(["elec_contract_id" => $elec->id])->update([
                    "elec_contract_id" => $elec->id,
                    "type" => $record->type,
                    "context" => json_encode(empty($resultVo->getData()["signatories"]) ? [] : $resultVo->getData()["signatories"]),
                ]);
            }
        }
        //写入DB
        return [
            "contractState" => $contractState,
            "contractNo" => $resultVo->getData()["contractNo"] ?? "",
            "error" => $resultVo->getMsg()
        ];
    }

    //签署合同
    public function agreeContract(array $params): array
    {
        $store = Store::query()->where("store_id", $params["store_id"])->first();
        if (empty($store)) {
            throw new \Exception("店铺不存在");
        }

        //是否存在合同
        $elecContracts = ElecContracts::query()->where([
            "store_id" => $store->store_id,
            "api_type" => $this->api,
            "company" => $params["company"]
        ])->first();
        if (empty($elecContracts)) {
            throw new \Exception("请先创建合同");
        }

        //获取开户信息
        $record = ElecOpenAccountRecords::query()->where([
            "store_id" => $store->store_id,
            "api_type" => $this->api,
        ])->first();
        if (empty($record) || $record->open == 0) {
            throw new \Exception("开户信息不存在");
        }
        $resultVo = $this->electronicSignature->agreeContract([
            "contractNo" => $elecContracts->contractNo,
            "userId" => $record->user_id,
        ]);
        if ($resultVo->getCode() == $resultVo->codeMap["ok"]) {
            //成功发送签署合同的短信
            $el = ElecContractSignatories::query()->where("elec_contract_id", $elecContracts->id)->first();
            if (!empty($el)) {
//                {"userId":"39126292503E6231E050007F01005DB1","authorizationTime":"20190801095509","location":"211.94.108.226","signLocation":"Signature2","projectCode":"003"}
                $el->authorizationTime = $resultVo->getData()["signInfo"]["authorizationTime"];
                $el->location = $resultVo->getData()["signInfo"]["location"];
                $el->signLocation = $resultVo->getData()["signInfo"]["signLocation"];
                $el->projectCode = $resultVo->getData()["signInfo"]["projectCode"];
//                $el->textValueInfo = $resultVo->getData()["signInfo"]["textValueInfo"];
                $el->userId = $resultVo->getData()["signInfo"]["userId"];
                $el->save();
            }
        } else {
            throw  new \Exception("签署合同失败");
        }
        return [
            "contractNo" => $elecContracts->contractNo,
            "userId" => $record->user_id,
        ];
    }

    //合同查询
    public function queryContract(array $params): array
    {
        $store = Store::query()->where("store_id", $params["store_id"])->first();
        if (empty($store)) {
            throw new \Exception("店铺不存在");
        }
        //是否存在合同
        $elecContracts = ElecContracts::query()->where([
            "store_id" => $store->store_id,
            "api_type" => $this->api,
            "company" => $params["company"]
        ])->first();
        if (empty($elecContracts)) {
            throw new \Exception("请先创建合同");
        }
//        else if ($elecContracts->contractState == 1) {
//            throw new \Exception("合同创建成功");
//        } else if ($elecContracts->contractState == 2) {
//            throw new \Exception("合同已经拒绝");
//        }
        if ($this->api == "gtxy") {

        } else if ($this->api == "easypay") {
            $resultVo = $this->electronicSignature->queryContract([
                "contractNo" => $elecContracts->contractNo,
            ]);
            if ($resultVo->getCode() == $resultVo->codeMap["ok"]) {
                //查询合同成功,更新合同状态  和签署状态
                $elecContracts->contractState = $resultVo->getData()["contractState"];
                $elecContracts->save();
                //签署信息
                ElecContractSignatories::query()->where("elec_contract_id", $elecContracts->id)
                    ->update([
                        "context" => empty($resultVo->getData()["signatories"]) ? "[]" : json_encode($resultVo->getData()["signatories"]),
                        "signState" => empty($resultVo->getData()["signState"]) ? 0 : $resultVo->getData()["signState"],
                    ]);
            } else {
                throw new \Exception($resultVo->getMsg());
            }
        }
        return [
            "contractNo" => $elecContracts->contractNo,
            "contractState" => $elecContracts->contractState
        ];
    }

    //合同下载
    public function downloadContract(array $params): array
    {
        $store = Store::query()->where("store_id", $params["store_id"])->first();
        if (empty($store)) {
            throw new \Exception("店铺不存在");
        }
        //是否存在合同
        $elecContracts = ElecContracts::query()->where([
            "store_id" => $store->store_id,
            "api_type" => $this->api,
            "company" => $params["company"]
        ])->first();
        if (empty($elecContracts)) {
            throw new \Exception("请先创建合同");
        }
        $resultVo = $this->electronicSignature->downloadContract([
            "contractNo" => $elecContracts->contractNo,
        ]);
//        pdfFileData
        //下载完成保存到oss上
        if ($resultVo->getCode() == $resultVo->codeMap["ok"]) {
            //保存合同文件
            $file = $resultVo->getData()["pdfFileData"];
            if (!is_dir(public_path("/contract") . date("/Y/m"))) {
                mkdir(public_path("/contract") . date("/Y/m"), 0777, true);
            }
            $baseUrlFile = public_path("/contract") . date("/Y/m") . time() . ".pdf";
            file_put_contents($baseUrlFile, file_get_contents($file));
            $elecContracts->url = $baseUrlFile;
            $elecContracts->save();
        } else {
            throw new \Exception($resultVo->getMsg());
        }
        return [
            "url" => $baseUrlFile,
        ];
    }


}






